using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;

namespace GoodStuff
{
    /// <summary>
    /// implements a UI progress bar control
    /// bindings: { value, minimum, maximum, text }
    /// </summary>
    public class GoodProgressBar : GoodControlBase
    {
        IGoodConvertibleVariable _minimum;
        IGoodConvertibleVariable _maximum;
        IGoodConvertibleVariable _value;

        ProgressBar _bar;

        public override void Initialize()
        {
            base.Initialize();

            _value = ParameterNumericVariable("Variable");
            _value.ValueChanged += OnVariableChanged;

            Trace.WriteLine("Initializing GoodProgressBar " + _value.InstanceName);

            _minimum = ParameterNumericVariable("Minimum");
            if (_minimum != null)
                _minimum.ValueChanged += OnVariableChanged;
            _maximum = ParameterNumericVariable("Maximum");
            if (_maximum != null)
                _maximum.ValueChanged += OnVariableChanged;

            _bar = new ProgressBar();
            GroupBox ggb = new GroupBox();
            if (ParameterText("Width") != null)
                ggb.Width = Int32.Parse(ParameterText("Width"));
            if (ParameterText("Height") != null)
                ggb.Height = Int32.Parse(ParameterText("Height"));

            ggb.Margin = new Padding(5,15, 5, 5);
            ggb.Text = ParameterText("Text");
            ggb.SizeChanged += new EventHandler(HandleSizeChanged);
            _control = ggb;
            ggb.Controls.Add(_bar);
            HandleSizeChanged(this, new EventArgs());

            UpdateValues();
        }

        protected void HandleSizeChanged(object sender, EventArgs args)
        {
            _bar.Size = new Size(
                _control.Size.Width - _control.Margin.Horizontal,
                _control.Size.Height - _control.Margin.Vertical);
            _bar.Location = new Point(
                _control.Margin.Left,
                _control.Margin.Top);
        }

        protected override void OnVariableChanged(object sender, EventArgs args)
        {
            if (_control.InvokeRequired)
                _control.Invoke(new UpdateDelegate(UpdateValues));
            else
                UpdateValues();
        }

        private delegate void UpdateDelegate();

        private void UpdateValues()
        {
             if (_minimum != null)
                _bar.Minimum = _minimum.ToInt32(null);
            else
                _bar.Minimum = 0;

            if (_maximum != null)
                _bar.Maximum = _maximum.ToInt32(null);
            else
                _bar.Maximum = Int32.MaxValue;

            _bar.Value = Math.Min(_bar.Maximum, Math.Max(_bar.Minimum,_value.ToInt32(null)));
       }
    }
}
